﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;

namespace SharpWeb
{
    /// <summary>
    /// Html标签组件
    /// </summary>
    public abstract class TagComponent : FunctionalComponent
    {
        public TagComponent()
        { 
            _Attributes = new TagAttributeCollection(); 
        }
        #region 属性

        /// <summary>
        /// 在派生类中重写以确定此组件所对应的标签名称
        /// </summary>
        protected virtual string TagName
        {
            get { return ""; }
        }
        /// <summary>
        /// 获取此组件描述的标签是否为自结束标签,自结束标签将不会绘制内容和结束标签
        /// </summary>
        protected virtual bool CloseItSelf
        {
            get { return true; }
        }

        private readonly TagAttributeCollection _Attributes;

        public TagAttributeCollection Attributes
        {
            get { return _Attributes; }
        }

        /// <summary>
        /// 获取或设置标签的Id属性
        /// </summary>
        public string Id
        {
            get { return this.Attributes["id"]; }
            set { this.Attributes["id"] = value; }
        }
        /// <summary>
        /// 获取或设置标签的Name属性
        /// </summary>
        public string Name
        {
            get { return this.Attributes["name"]; }
            set { this.Attributes["name"] = value; }
        }

        #endregion

        #region 事件属性 

        public string onclick
        {
            get { return this.Attributes["onclick"]; }
            set { this.Attributes["onclick"] = value; }
        }

        public string ondblclick
        {
            get { return this.Attributes["ondblclick"]; }
            set { this.Attributes["ondblclick"] = value; }
        }
        public string onfocus
        {
            get { return this.Attributes["onfocus"]; }
            set { this.Attributes["onfocus"] = value; }
        }
        public string onblur
        {
            get { return this.Attributes["onblur"]; }
            set { this.Attributes["onblur"] = value; }
        }
        public string onmousedown
        {
            get { return this.Attributes["onmousedown"]; }
            set { this.Attributes["onmousedown"] = value; }
        }
        public string onmouseup
        {
            get { return this.Attributes["onmouseup"]; }
            set { this.Attributes["onmouseup"] = value; }
        }
        public string onmouseover
        {
            get { return this.Attributes["onmouseover"]; }
            set { this.Attributes["onmouseover"] = value; }
        }
        public string onmousemove
        {
            get { return this.Attributes["onmousemove"]; }
            set { this.Attributes["onmousemove"] = value; }
        }
        public string onmouseout
        {
            get { return this.Attributes["onmouseout"]; }
            set { this.Attributes["onmouseout"] = value; }
        }
        public string onkeypress
        {
            get { return this.Attributes["onkeypress"]; }
            set { this.Attributes["onkeypress"] = value; }
        }
        public string onkeydown
        {
            get { return this.Attributes["onkeydown"]; }
            set { this.Attributes["onkeydown"] = value; }
        }
        public string onkeyup
        {
            get { return this.Attributes["onkeyup"]; }
            set { this.Attributes["onkeyup"] = value; }
        }
        #endregion

        #region Render
        /// <summary>
        /// 在内部调用，开始渲染标签组件
        /// </summary>
        /// <param name="context"></param>
        /// <param name="sb"></param>
        internal void RenderComponent( StringBuilder sb,ComponentContext context)
        {
            sb.Append(this.OnRender(context));
        }
        /// <summary>
        /// 在派生类中重写以渲染可视组件的内容
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        protected virtual string OnRender(ComponentContext context)
        {
            StringBuilder sb = new StringBuilder();
            this.OnRenderBegining(sb, context);
            sb.Append('<');
            this.OnRenderTagName(sb, context);
            sb.Append(" ");//标签名称后的空格
            this.OnRenderTagAttributes(sb, context);
            if (this.CloseItSelf)
            {
                sb.Append(" />");
            }
            else
            {
                this.OnRenderContent(sb, context);
                this.OnRenderTagEnd(sb, context);
            }
            this.OnRenderEnded(sb, context);

            return sb.ToString();
        }

        /// <summary>
        /// 在所有绘制之前
        /// </summary>
        /// <param name="sb"></param>
        /// <returns></returns>
        protected virtual void OnRenderBegining(StringBuilder sb, ComponentContext context)
        {

        }

        /// <summary>
        /// 绘制标签名称
        /// </summary>
        /// <param name="sb"></param>
        /// <returns></returns>
        protected virtual void OnRenderTagName(StringBuilder sb, ComponentContext context)
        {
            sb.Append(this.TagName);
        }

        /// <summary>
        /// 在派生类中重写以绘制标签的属性，
        /// 默认绘制Attributes属性中的全部内容。
        /// </summary>
        /// <param name="sb"></param>
        /// <returns></returns>
        protected virtual void OnRenderTagAttributes(StringBuilder sb, ComponentContext context)
        {
            foreach (TagAttribute item in this.Attributes)
            {
                sb.Append(item.ToString() + " ");
            }
        }

        /// <summary>
        /// 绘制内容
        /// </summary>
        /// <param name="sb"></param>
        /// <returns></returns>
        protected virtual void OnRenderContent(StringBuilder sb, ComponentContext context)
        {

        }
        /// <summary>
        /// 绘制结束标签
        /// </summary>
        /// <param name="sb"></param>
        /// <returns></returns>
        protected virtual void OnRenderTagEnd(StringBuilder sb, ComponentContext context)
        {
            sb.Append("</");
            sb.Append(this.TagName);
            sb.Append('>');
        }
        /// <summary>
        /// 在所有绘制之完成之后
        /// </summary>
        /// <param name="sb"></param>
        /// <returns></returns>
        protected virtual void OnRenderEnded(StringBuilder sb, ComponentContext context)
        {

        }
        #endregion
    }
}
